package com.hehanpeng.springbootnetty.busi.busiservice;

import com.google.common.collect.Maps;
import com.hehanpeng.springbootnetty.annotation.BusiService;
import org.springframework.context.ApplicationContext;

import java.util.Map;

/**
 * spring 上下文
 */
public class SpringBusiServiceManager {
    private static ApplicationContext applicationContext;

    private static Map<String, BaseBusiService> BusiServiceMap = Maps.newHashMap();

    private static Map<String, String> BusiCodeMap = Maps.newHashMap();

    private static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 注册服务  在启动类中调用本方法，将处理类添加到map中,processCode作为key
     *
     * @param applicationContext 上下文
     */
    public static void register(ApplicationContext applicationContext) {
        SpringBusiServiceManager.applicationContext = applicationContext;
        annotationRegister();
    }

    /**
     * 注册BusiService  通过注解获取processCode作为key,将BusiService添加到map
     */
    private static void annotationRegister() {
        Map<String, Object> beans = applicationContext.getBeansWithAnnotation(BusiService.class);
        beans.forEach((s, serviceBean) -> {
            if (!(serviceBean instanceof BaseBusiService)) {
                throw new Error("@BusiService should only be used on BaseBusiService");
            }
            BaseBusiService baseBusiService = (BaseBusiService) serviceBean;
            BusiService busiService = serviceBean.getClass().getAnnotation(BusiService.class);
            if (busiService == null) {
                throw new Error("@BusiService annotation used error.");
            }
            String reqMsgCode = busiService.reqMsgCode();
            String respMsgCode = busiService.respMsgCode();
            String s1 = BusiCodeMap.get(reqMsgCode);
            if (s1 != null) {
                if (!respMsgCode.equals(s1)) {
                    throw new Error("@BusiService annotation respMsgCode was used.");
                }
            }
            String processCode = busiService.processCode();
            String key = reqMsgCode + "/" + processCode;
            BusiServiceMap.put(key, baseBusiService);
            BusiCodeMap.put(reqMsgCode, respMsgCode);
        });
    }

    /**
     * 获取交易处理码
     *
     * @param processCode 交易处理码
     * @return 交易处理类
     */
    public static BaseBusiService getMessageHandler(String mti, String processCode) {
        return BusiServiceMap.get(mti + "/" + processCode);
    }
}
